package serveur.controller;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

import serveur.model.dao.ImageDAO;
import serveur.model.dao.Singleton;
import serveur.model.entite.FichierImage;
import serveur.model.entite.Joueur;
/**
 * 
 * @author michael
 *
 */
public class Partie {
	private List<FichierImage> listImage;
	private Map<Joueur,Socket> mapJoueur;
	private FichierImage currentImage = null;
	private AtomicBoolean endPartie;
	private String nomPartie;
	private Joueur joueur;
	private static HashMap<String,Partie> listePartie = new HashMap<String, Partie>();
	//constructeur d"une partie
	public Partie (String nomPartie) {
		this.nomPartie = nomPartie;
		initListImage();
		this.mapJoueur = new HashMap<Joueur, Socket>();
		listePartie.put(nomPartie, this);
		//init la 1er image
		System.out.println("une partie � �t� cree "+nomPartie);
	}
	//selectionne 10 image al�atoirement pour la partie, et initialise l'image courante
	public void initListImage(){
		ImageDAO imageDao = new ImageDAO(Singleton.getInstance());
		List<FichierImage> imageTemp = new ArrayList<FichierImage>();
		listImage = new ArrayList<FichierImage>();
		imageTemp = imageDao.findAllImage();
		Random r = new Random();
		int nb;
		
		while(listImage.size()<10){
			nb = r.nextInt(imageTemp.size());
			listImage.add(imageTemp.get(nb));
			imageTemp.remove(imageTemp.get(nb));
		}
		this.currentImage = listImage.get(0);
		listImage.remove(0);
		
	}
	//permet l"ajout d"un joueur a la partie
	public void addJoueurPartie (Joueur joueur,Socket s) {
		this.joueur=joueur;
		this.mapJoueur.put(joueur, s);
	}
	//supprime un joueur de la partie
	public void removeJoueurPartie (Joueur joueur) {
		mapJoueur.remove(joueur);
	}
	//lorsque q'un joueur gagne une manche, l"image change et est renvoy� ver les joueur de cette partie
	public void gagner(){
		if(listImage.size()!=0){
			this.currentImage = listImage.get(0);
			listImage.remove(0);
			joueur.gagnier();
			String send = "Jouer:"+this.getCurrentImage().getId()+"-"+this.getCurrentImage().getReponse()+"\n";
			broadcast(send);
		}
	}
	//retourne l'image cournte de la partie
	public FichierImage getCurrentImage(){
		return currentImage;
	}
	//retourne boolean celon l'�tat de la partie
	public boolean finie() {
		if(listImage.size()==0){
			listePartie.remove(nomPartie);
			broadcast("PartieFinie:\n");
			getScore();
			return false;
		}
		return true;
	}
	//retourne une partie par son nom
	public static Partie getPartieIntoListe(String nomPartie) {
		nomPartie = nomPartie.substring(0, nomPartie.length()-1);
		Partie entry = listePartie.get(nomPartie);
		System.out.println("partie trouv� : "+entry.nomPartie);
		
		return listePartie.get(nomPartie);
	}
	//retourne la map des partie
	public static HashMap<String, Partie> getListePartie() {
		return listePartie;
	}
	public String partieEnCours(){
		return "partieEnCours:"+nomPartie+","+joueur.getPseudo();
	}
	public static void setListePartie(HashMap<String, Partie> listePartie) {
		Partie.listePartie = listePartie;
	}
	//permet l'envois d'un message a tout les joueurs de la partie 
	private void broadcast(String send){
		Map<Joueur, Socket> mapTemp = mapJoueur;
		Socket s;
		BufferedWriter fluxSortie;
		for(Map.Entry<Joueur, Socket> entry : mapTemp.entrySet()){
			s=entry.getValue();
			try {
				fluxSortie = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
				fluxSortie.write(send);
				fluxSortie.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	public void getScore(){
		Map<Joueur, Socket> mapTemp = mapJoueur;
		Socket s;
		for(Map.Entry<Joueur, Socket> entry : mapTemp.entrySet()){
			s=entry.getValue();
			broadcast("Score:"+entry.getKey().getPseudo()+","+joueur.getScore()+"\n");
			
		}
	}
	public String getNomPartie() {
		return nomPartie;
	}
	
	public void setNomPartie(String nomPartie) {
		this.nomPartie = nomPartie;
	}
}
